/******************************************************************************
 * Copyright 2022 The Untouch Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/calibration/lidar_imu_calibrator/include/load_data_dialog.h"

#include <QCloseEvent>
#include <QFileDialog>
#include <QMessageBox>

#include "ui_load_data_dialog.h"

LoadDataDialog::LoadDataDialog(
    std::shared_ptr<lidar_imu_calibrator::OdometryFrameSet> odometry_frame_set,
    QWidget *parent)
    : QDialog(parent),
      ui(new Ui::LoadDataDialog),
      odometry_frame_set_(odometry_frame_set),
      start_flag_(false) {
  ui->setupUi(this);
  this->setFixedSize(this->size());
  ui->progressBar->setMinimum(0);
  ui->progressBar->setMaximum(100);
  ui->progressBar->setValue(0);
  connect(odometry_frame_set_.get(),
          &lidar_imu_calibrator::OdometryFrameSet::ProgressChanged, this,
          &LoadDataDialog::ProgressChanged);
  ui->txtExtrinsicFilePath->setText(
      "/apollo/data/lidar_imu/hesai64_novatel_extrinsics.yaml");
  ui->txtOdometryFilePath->setText("/apollo/data/lidar_imu/sensor_lidar/odometry_localization.csv");
  ui->txtPcdFolderPath->setText("/apollo/data/lidar_imu/sensor_lidar");
}

LoadDataDialog::~LoadDataDialog() { delete ui; }

void LoadDataDialog::closeEvent(QCloseEvent *event) {
  if (start_flag_) {
    if (QMessageBox::question(
            this, QStringLiteral("Prompt"),
            QStringLiteral("Are you sure you want to exit the load data?"),
            QMessageBox::Yes | QMessageBox::No,
            QMessageBox::No) == QMessageBox::No) {
      event->ignore();
      return;
    }
    Stop();
  }
  event->accept();
}

void LoadDataDialog::on_btnExtrinicBrowser_clicked() {
  QString fileName = QFileDialog::getOpenFileName(
      this, QStringLiteral("select extrinsic file"), "/apollo/data/bag",
      tr("yaml (*.yaml)"));
  if (!fileName.isEmpty()) {
    this->ui->txtExtrinsicFilePath->setText(fileName);
  }
}

void LoadDataDialog::on_btnOdometryFileBrowser_clicked() {
  QString fileName =
      QFileDialog::getOpenFileName(this, QStringLiteral("select odometry file"),
                                   "/apollo/data/bag", tr("csv (*.csv)"));
  if (!fileName.isEmpty()) {
    this->ui->txtOdometryFilePath->setText(fileName);
  }
}

void LoadDataDialog::on_btnPcdFolderBrowser_clicked() {
  QString dir_name = QFileDialog::getExistingDirectory(
      this, QString("Pcd Folder"), "/apollo/data/bag");
  if (!dir_name.isEmpty()) {
    this->ui->txtPcdFolderPath->setText(dir_name);
  }
}

void LoadDataDialog::on_btnLoad_clicked() {
  if (start_flag_) {
    if (QMessageBox::question(
            this, QStringLiteral("Prompt"),
            QStringLiteral(
                "Are you sure you want to stop the load data?"),
            QMessageBox::Yes | QMessageBox::No,
            QMessageBox::No) == QMessageBox::Yes) {
      Stop();
    }
  } else {
    Start();
  }
}

void LoadDataDialog::on_btnCancel_clicked() { close(); }

void LoadDataDialog::ProgressChanged(int percent) {
  if (this->ui->progressBar->value() != percent) {
    this->ui->progressBar->setValue(percent);
    if (percent == 100) {
      Stop();
      accept();
    }
  }
}

void LoadDataDialog::Start() {
  if (!IsInputValid()) {
    return;
  }

  if (!odometry_frame_set_->StartLoad(pcd_folder_path_.toStdString(),
                                      odometry_file_path_.toStdString(),
                                      extrinic_file_path_.toStdString())) {
    QMessageBox::warning(
        this, QStringLiteral("Prompt"),
        QStringLiteral("Load Cloud Point failed, please check log!"));
    return;
  }
  EnableControls(false);
  this->ui->btnLoad->setText("Stop");
  start_flag_ = true;
}

void LoadDataDialog::Stop() {
  odometry_frame_set_->Stop();
  this->ui->btnLoad->setText("Load");
  EnableControls(true);
  start_flag_ = false;
}

bool LoadDataDialog::IsInputValid() {
  extrinic_file_path_ = this->ui->txtExtrinsicFilePath->text();
  if (extrinic_file_path_.isEmpty()) {
    QMessageBox::warning(
        this, QStringLiteral("Prompt"),
        QStringLiteral("Extrinsic File Path is empty, please enter!"));
    return false;
  }

  odometry_file_path_ = this->ui->txtOdometryFilePath->text();
  if (odometry_file_path_.isEmpty()) {
    QMessageBox::warning(
        this, QStringLiteral("Prompt"),
        QStringLiteral("Odometry File Path is empty, please enter!"));
    return false;
  }

  pcd_folder_path_ = this->ui->txtPcdFolderPath->text();
  if (pcd_folder_path_.isEmpty()) {
    QMessageBox::warning(
        this, QStringLiteral("Prompt"),
        QStringLiteral("Pcd Folder Path is empty, please enter!"));
    return false;
  }
  return true;
}

void LoadDataDialog::EnableControls(bool enable) {
  this->ui->txtExtrinsicFilePath->setEnabled(enable);
  this->ui->btnExtrinicBrowser->setEnabled(enable);
  this->ui->txtOdometryFilePath->setEnabled(enable);
  this->ui->btnOdometryFileBrowser->setEnabled(enable);
  this->ui->txtPcdFolderPath->setEnabled(enable);
  this->ui->btnPcdFolderBrowser->setEnabled(enable);
}
